package com.huawei.esdk.uc.sametime.widgets;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import com.huawei.esdk.uc.jna.UCService;
import com.huawei.esdk.uc.jna.Constants.AccountType;
import com.huawei.esdk.uc.jna.Constants.ContactAvailability;
import com.huawei.esdk.uc.jna.Constants.UCServiceRetvCode;
import com.huawei.esdk.uc.jna.struct.STAudioVideoParam;
import com.huawei.esdk.uc.jna.struct.STVideoCallParam;
import com.huawei.esdk.uc.jna.util.StringUtil;
import com.huawei.esdk.uc.sametime.ConstantsDefines;
import com.huawei.esdk.uc.sametime.ConstantsDefines.CallMode;
import com.huawei.esdk.uc.sametime.ConstantsDefines.CallStatus;
import com.huawei.esdk.uc.sametime.history.ui.EsdkUCHistoryView;
import com.huawei.esdk.uc.sametime.international.Messages;
import com.huawei.esdk.uc.sametime.models.Participant;
import com.huawei.esdk.uc.sametime.models.ParticipantList;
import com.huawei.esdk.uc.sametime.services.UCCallService;
import com.huawei.esdk.uc.sametime.services.UCHistoryService;
import com.huawei.esdk.uc.sametime.services.UCSettingsService;
import com.huawei.esdk.uc.sametime.util.ImageFactory;
import com.huawei.esdk.uc.sametime.util.PluginUtil;
import com.ibm.collaboration.realtime.people.PeopleUtil;
import com.sun.jna.Structure;

/**
 * 创建来电弹窗单例类
 * @author lWX169831
 * 
 */
public class CallComeInPopup
{
    private static Logger logger = Logger.getLogger(CallComeInPopup.class);

    private static CallComeInPopup instance;

    private Shell shell;

    private int moveStep = 2; // 每次移动的pixel

    private int upPosition; // 能移动到的最上面坐标

    private int downPosition; // 当前popup的边框坐标

    private int leftPosition; // popup左边边框坐标

    private Label avatorLabel;

    private Label statusLable;

    private Label nameLable;

    private Label videoLable;

    private Label forwardLabel;

    private Button receiveButton;

    private Button rejectButton;

    private Button forwardButton;

    private Text forwardNumberField;

    private boolean flag = false;

    private boolean isVideo = false;

    private boolean isRecived = false;

    private String ucAccount = "";

    private Thread thread;

    private Runnable runnable;

    private CallComeInPopup()
    {
        runnable = new Runnable()
        {
            @Override
            public void run()
            {
                // 为了解决外面获取display对象，内部又做一次shell非空判断的CI报错问题
                Display display = null;// shell.getDisplay();
                while (flag)
                {
                    try
                    {
                        Thread.sleep(10);

                        // 判断当前位置是否小于能出现的最高位置，小于的话就说明还可以向上移动。
                        if ((downPosition - moveStep) > upPosition)
                        {
                            // 存在通话弹出窗口向上弹出过程中,通话结束导致shell为空的问题
                            if (null != shell)
                            {
                                display = shell.getDisplay();
                                display.asyncExec(new Runnable()
                                {
                                    @Override
                                    public void run()
                                    {
                                        shell.setLocation(leftPosition,
                                                downPosition - moveStep);
                                        downPosition -= moveStep;
                                    }
                                });
                                // 此时已经移动到了最高位置，显示5秒钟后，关闭窗口并退出。
                            }

                        }
                        else
                        {
                            flag = false;
                        }
                    }
                    catch (InterruptedException exception)
                    {
                        logger.error(exception);
                    }
                }
            }
        };
    }

    public static CallComeInPopup getInstance()
    {
        if (null == instance)
        {
            instance = new CallComeInPopup();
        }
        return instance;
    }

    public static void destroyInstace()
    {
        instance = null;
    }

    /**
     * 创建来电的弹出窗口
     */
    private void createPopup()
    {
        shell = new Shell(SWT.ON_TOP);

        avatorLabel = new Label(shell, SWT.NONE);
        avatorLabel.setBounds(10, 10, 35, 35); // (left, top, width, high)

        statusLable = new Label(shell, SWT.NONE);
        statusLable.setBounds(45, 10, 20, 20);

        nameLable = new Label(shell, SWT.SINGLE | SWT.WRAP);
        nameLable.setBounds(65, 10, 150, 20);

        // closeLable = new Label(shell, SWT.NONE);
        // closeLable.setBounds(225, 0, 20, 20);

        int offset = 0;
        if (isVideo)
        {
            videoLable = new Label(shell, SWT.NONE);
            videoLable.setBounds(80, 50, 60, 60);
            videoLable.setImage(ImageFactory.loadImage(Display.getCurrent(),
                    ImageFactory.VIDEO_CALL));

            offset = 60;
        }

        forwardLabel = new Label(shell, SWT.NONE);
        forwardLabel.setBounds(25, 55 + offset, 200, 20);
        forwardLabel.setText(Messages.CallComeInPopup_FORWARD);

        forwardNumberField = new Text(shell, SWT.BORDER);
        forwardNumberField.setBounds(25, 75 + offset, 200, 25);

        receiveButton = new Button(shell, SWT.SINGLE | SWT.PUSH);
        receiveButton.setBounds(25, 75 + offset + 30, 60, 25);
        receiveButton.setText(Messages.CallComeInPopup_ANSWER);

        rejectButton = new Button(shell, SWT.SINGLE | SWT.PUSH);
        rejectButton.setBounds(95, 75 + offset + 30, 60, 25);
        rejectButton.setText(Messages.CallComeInPopup_REJECT);

        forwardButton = new Button(shell, SWT.SINGLE | SWT.PUSH);
        forwardButton.setBounds(165, 75 + offset + 30, 60, 25);
        forwardButton.setText(Messages.TRANSFER);
        forwardButton.setEnabled(false);

        shell.setSize(245, 115 + offset + 30);
        // 取屏幕大小
        Rectangle area = Display.getDefault().getClientArea();
        upPosition = area.height - (115 + offset + 30);// 计算出popup界面在屏幕显示的最高位置
        downPosition = area.height + (115 + offset + 30);// 计算出popup界面的初始位置
        leftPosition = area.width - 250;
        // 初始化popup位置
        shell.setLocation(leftPosition, downPosition);
        shell.open();
    }

    private void setAccount(byte[] acByte)
    {
        ucAccount = StringUtil.bytesToString(acByte);
    }

    public void showComeInPopup(Structure param)
    {
        if (param instanceof STAudioVideoParam)
        {
            STAudioVideoParam avParam = (STAudioVideoParam) param;
            logger.debug("showComeInPopup " + avParam.isvideo + ", "
                    + avParam.callMode + ", " + avParam.accountType);
            isVideo = (1 == avParam.isvideo);
            setAccount(avParam.ucAcc);
        }
        else
        {
            STVideoCallParam vcParam = (STVideoCallParam) param;
            logger.debug("showComeInPopup update video");
            isVideo = true;
            setAccount(vcParam.ucAcc);
        }

        if (null == shell)
        {
            createPopup();
        }

        avatorLabel.setImage(ImageFactory.loadImage(Display.getCurrent(),
                ImageFactory.AVATOR_DEFAULT));
        statusLable.setImage(ImageFactory.loadImage(Display.getCurrent(),
                ImageFactory.STATUS_BUSY));
        nameLable.setText(ucAccount);

        receiveButton.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent selectionevent)
            {
                super.widgetSelected(selectionevent);
                isRecived = true;
                showCallWindow();
                closeComeInPopup();
            }
        });
        rejectButton.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent selectionevent)
            {
                super.widgetSelected(selectionevent);
                if (!isVideo)
                {
                    UCService.getInstance().UC_SDK_RejectCall();
                }
                else
                {
                    UCService.getInstance().UC_SDK_RejectVideoCall();
                }

                closeComeInPopup();
            }
        });

        forwardNumberField.addModifyListener(new ModifyListener()
        {
            @Override
            public void modifyText(ModifyEvent modifyevent)
            {
                String numToCall = forwardNumberField.getText().trim();
                int len = forwardNumberField.getText().length();
                if (len > 0)
                {
                    // 如果不是合法的输入,则需要将最后一位去掉
                    if (!PluginUtil.checkTelephone(numToCall))
                    {
                        String newString = forwardNumberField.getText()
                                .substring(0, len - 1);
                        forwardNumberField.setText(newString);
                        forwardNumberField.setSelection(newString.length());
                    }

                    forwardButton.setEnabled(true);
                }
                else
                {
                    forwardButton.setEnabled(false);
                }
            }
        });

        forwardButton.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent selectionevent)
            {
                String numToCall = forwardNumberField.getText().trim();

                if (!StringUtil.isEmptyStr(numToCall))
                {
                    UCService.getInstance().UC_SDK_ForwardCall(
                            AccountType.UC_IPPHONE, numToCall);
                    closeComeInPopup();
                }
            }
        });
        thread = new Thread(runnable);
        flag = true;
        thread.start();
    }

    public void closeComeInPopup()
    {
        flag = false;
        isVideo = false;
        if (null != shell)
        {
            logger.debug("try to close call window");
            shell.close();
            shell = null;

            if (!isRecived
                    && CallStatus.connected != UCCallService.getCallStatus())
            {
                int ret = UCHistoryService.insertCallHistory(ucAccount,
                        ucAccount, -1);
                if (UCServiceRetvCode.UC_SDK_Success == ret)
                {
                    if (null != EsdkUCHistoryView.getInstance())
                    {
                        EsdkUCHistoryView.getInstance().freshCallHistory();
                    }
                }
                UCCallService.setCallMode(CallMode.invalid);
                UCCallService.setCallStatus(CallStatus.end);

                // 发布自己的状态
                UCService.getInstance().UC_SDK_PubSelfStatus(
                        ContactAvailability.Online, "");
                PeopleUtil.getLocalPerson().refreshStatus();
            }
        }
        if (null != thread)
        {
            thread = null;
        }

        isRecived = false;

        CallComeInPopup.destroyInstace();
    }

    /**
     * 来电被接听之后用来弹出来电窗口的方法
     */
    public void showCallWindow()
    {
        logger.debug("try to pop up call window");
        Participant participant = new Participant();
        ParticipantList participantList = new ParticipantList();

        participant.setUcAccount(ucAccount);
        participant.setNumber(ucAccount);
        participantList.addparticipants(participant);

        EsdkUCConvWindow window = EsdkUCConvWindow.getInstance();
        window.createUCConvWindow(participantList);
        window.acceptCall(isVideo);
    }

    /**
     * 话机联动 来电被接听之后用来弹出来电窗口的方法
     */
    public void showCallWindowForPhone()
    {
        if (null != shell)
        {
            isRecived = true;

            logger.debug("try to pop up call window");
            Participant participant = new Participant();
            ParticipantList participantList = new ParticipantList();

            participant.setUcAccount(ucAccount);
            participant.setNumber(ucAccount);
            participantList.addparticipants(participant);

            EsdkUCConvWindow window = EsdkUCConvWindow.getInstance();
            window.createUCConvWindow(participantList);
            if(ConstantsDefines.IP_PHONE_MODE.equals(UCSettingsService.getPhoneJoinDev()))
            {
                isVideo = false;
            }
            window.connectedForPhone(isVideo);

            closeComeInPopup();
        }
    }
}
